package main

import "fmt"

// MyBitMap 自定义位图结构体
type MyBitMap struct {
	elem     []byte // 字节数组
	usedSize int    // 存储的元素个数
}

// initBitMap 初始化函数
func initBitMap(bitMap *MyBitMap) {
	bitMap.elem = make([]byte, 1, 5)
	bitMap.usedSize = 0
}

// set 添加元素
func (bitMap *MyBitMap) set(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 使用或运算
	bitMap.elem[elemIndex] |= 1 << bitIndex
	// 4. 存储元素个数+1
	bitMap.usedSize++
}

// get 查找某个元素是否存在
func (bitMap *MyBitMap) get(num int) bool {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 使用与运算
	return !(bitMap.elem[elemIndex]&(1<<bitIndex) == 0)
}

// reset 重置某个元素
func (bitMap *MyBitMap) reset(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 查找元素是否存在
	if bitMap.get(num) {
		bitMap.usedSize--
	}
	// 4. 使用 ~运算 + &运算
	bitMap.elem[elemIndex] &= ^(1 << bitIndex)
}

// reset2 重置某个元素
func (bitMap *MyBitMap) reset2(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 查找元素是否存在
	if bitMap.get(num) {
		// 使用异或
		bitMap.elem[elemIndex] ^= 1 << bitIndex
		bitMap.usedSize--
	} else {
		// nothing to do....
	}
}

// getUsedSize 获取已经存储元素个数
func (bitMap *MyBitMap) getUsedSize() int {
	return bitMap.usedSize
}

func main() {
	// 声明MyBitMap
	var myBitMap MyBitMap
	// 初始化MyBitMap
	initBitMap(&myBitMap)
	myBitMap.set(1)
	myBitMap.set(3)
	myBitMap.set(4)
	fmt.Println(myBitMap.get(7))
	myBitMap.set(7)
	fmt.Println(myBitMap.get(7))
	myBitMap.reset(7)
	fmt.Println(myBitMap.get(7))
	myBitMap.reset2(2)
	fmt.Println(myBitMap.getUsedSize())
}
